原始题目:剑指 Offer 53 - II. 0~n-1中缺失的数字 (opens new window)
# 方法一:二分法
因为数组已经排序好了,可以通过二分法去确定,缺失的是哪一个数字。
根据题意,可以将数组分为两部分:
- 左子数组:;
- 右子数组:;
缺失的数字应当等于右子数组第一个元素的索引。
代码:
public int missingNumber(int[] nums) {
if (nums[0] != 0){
return 0;
}
if (nums[nums.length-1] != nums.length){
return nums.length;
}
int i = 0, j = nums.length;
while (i <= j) {
int mid = (i + j) / 2;
if (nums[mid] == mid) {
i = mid + 1;
} else {
j = mid - 1;
}
}
return i;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
复杂度分析
- 时间复杂度:二分法为对数级别复杂度。
- 空间复杂度:辅助变量占用常数大小的额外空间。
# 方法二:异或
异或有两条性质:① 0 ^ a = a ; ② a ^ a = 0 。
因为数组中的数字都是唯一的,将数组内的元素全部进行异或操作,然后在和 ~ n 进行异或,最后会只剩下那个不在数组中的数字。
public int missingNumber(int[] nums) {
int xor = 0;
for (int num : nums) {
xor ^= num;
}
for (int i = 0; i <= nums.length; i++) {
xor ^= i;
}
return xor;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
复杂度分析
- 时间复杂度:算法进行 次循环。
- 空间复杂度:辅助变量占用常数大小的额外空间。